//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

#include "UI/Types/Types.h"
#include "UI/Types/ArrangeHelper.h"
#include "UI/Types/UpdateWidgetData.h"

namespace Engine
{
namespace UI
{


	//
	// Widget Message
	//

	struct WidgetMsgBase
	{	
		typedef MessageTempl< WidgetMsgBase >	WidgetMsg;


		//
		// Message Type
		//
		enum EType
		{
			UPDATE = 0,				// recursive
			DRAW,					// recursive

			ATTACH,
			DETACH,
			ATTACHED,
			DETACHED,

			ARRANGE,				// recursive

			ON_LOAD,				// recursive

			GET_WIDGET,				// recursive

			ON_INPUT,				// recursive

			PROCESS_AND_TRANSMIT,	// recursive

			SET_STATE,

			SET_COLOR_STYLE,
		};


		//
		// Base Message Type
		//
		template <EType MinValue, EType MaxValue>
		struct BaseMsg
		{
			static bool IsMessageTypeSupported (EType type)
			{
				return type >= MinValue and type <= MaxValue;
			}
		};


		//
		// Update
		//
		struct Update : BaseMsg< UPDATE, UPDATE >
		{
			// in
			Screen *			screen;
			float				timeDelta;		// time delta between updates in seconds
			UpdateWidgetData *	data;
			///
			explicit
			Update (Screen *scr, float dt, UpdateWidgetData &data) :
				screen(scr), timeDelta(dt), data(&data)
			{}
		};


		//
		// Draw
		//
		struct Draw : BaseMsg< DRAW, DRAW >
		{
			// in
			Screen *		screen;
			///
			explicit
			Draw (Screen *scr) : screen(scr)
			{}
		};


		//
		// Attach / Detach
		//
		struct Attach : BaseMsg< ATTACH, DETACHED >
		{
			// in
			Widget *	widget;		// attached/... widget
			Widget *	parent;		// new parent of attached/... widget
			///
			explicit
			Attach (Widget *widget, Widget *parent = null) :
				widget(widget), parent(parent)
			{}
		};


		//
		// Arrange
		//
		struct Arrange : BaseMsg< ARRANGE, ARRANGE >
		{
			// in
			const ArrangeHelper *	helper;
			///
			explicit
			Arrange (const ArrangeHelper &helper) :
				helper(&helper)
			{}
		};


		//
		// Empty Message
		//
		struct EmptyMessage : BaseMsg< ON_LOAD, ON_LOAD >
		{
			EmptyMessage () {}

			operator void () { return; }
		};


		//
		// Get Widget
		//
		struct GetWidget : BaseMsg< GET_WIDGET, GET_WIDGET >
		{
			// in
			const uni_c_string *	name;
			// inout
			Widget **				result;
			///
			explicit
			GetWidget (uni_c_string &name, Widget *&result) : name(&name), result(&result)
			{}
		};


		//
		// Widget Message
		//
		struct WidgetMessage : BaseMsg< PROCESS_AND_TRANSMIT, PROCESS_AND_TRANSMIT >
		{
			// in
			const WidgetMsg	*	msg;
			///
			explicit
			WidgetMessage (const WidgetMsg &msg) :
				msg(&msg)
			{}
		};


		//
		// Set State
		//
		struct SetState : BaseMsg< SET_STATE, SET_STATE >
		{
			// types
			enum EState
			{
				ENABLED,
				VISIBLE,
				CHECKED,
			};


			// in
			EState	state;
			bool	value;
			bool	recursive;
			///
			SetState (EState state, bool value, bool recursive = false) :
				state(state), value(value), recursive(recursive)
			{}
		};


		//
		// Set Color Style
		//
		struct SetColorStyle : BaseMsg< SET_COLOR_STYLE, SET_COLOR_STYLE >
		{
			// types
			enum ETarget
			{
				BACKGROUND = 0,
				IMAGE_CS,
				FONT_CS,
			};

			// in
			ColorStyle	cs;
			ETarget		target;
			///
			SetColorStyle (const ColorStyle &cs, ETarget target) : cs(cs), target(target)
			{}
		};
		
		typedef CompileTime::TypeList10< Update, Draw, Attach, Arrange, EmptyMessage, GetWidget,
										 WidgetMessage, SetState, SetColorStyle >::type		type_list_t;
	};

	typedef MessageTempl< WidgetMsgBase >	WidgetMsg;

}	// UI
}	// Engine